\subsubsection{x86}

\myparagraph{\NonOptimizing MSVC}

Рассмотрим пример, скомпилированный в (MSVC 2010):

\lstinputlisting[caption=MSVC 2010,style=customasmx86]{patterns/08_switch/2_lot/lot_msvc_RU.asm}

\myindex{jumptable}
Здесь происходит следующее: в теле функции есть набор вызовов \printf с разными аргументами. 
Все они имеют, конечно же, адреса, а также внутренние символические метки, которые присвоил им компилятор.
Также все эти метки указываются во внутренней таблице \TT{\$LN11@f}.

В начале функции, если $a$ больше 4, то сразу происходит переход на метку \TT{\$LN1@f}, 
где вызывается \printf с аргументом \TT{'something unknown'}.

А если $a$ меньше или равно 4, то это значение умножается на 4 и прибавляется адрес таблицы 
с переходами (\TT{\$LN11@f}). 
Таким образом, получается адрес внутри таблицы, где лежит нужный адрес внутри тела функции. 
Например, возьмем $a$ равным 2. $2*4 = 8$ (ведь все элементы таблицы~--- это адреса внутри 32-битного процесса, 
таким образом, каждый элемент занимает 4 байта). 8 прибавить к \TT{\$LN11@f}~--- это будет элемент таблицы,
где лежит \TT{\$LN4@f}. \JMP вытаскивает из таблицы адрес \TT{\$LN4@f} и делает безусловный переход туда.

Эта таблица иногда называется \IT{jumptable} или
\IT{branch table}\footnote{Сам метод раньше назывался 
\IT{computed GOTO} В ранних версиях Фортрана:
\href{http://go.yurichev.com/17122}{wikipedia}.
Не очень-то и полезно в наше время, но каков термин!}.

А там вызывается \printf с аргументом \TT{'two'}. 
Дословно, инструкция \TT{jmp DWORD PTR \$LN11@f[ecx*4]} 
означает \IT{перейти по DWORD, который лежит по адресу} \TT{\$LN11@f + ecx * 4}.

\TT{npad} (\myref{sec:npad}) это макрос ассемблера, выравнивающий начало таблицы, 
чтобы она располагалась по адресу кратному 4 (или 16).
Это нужно для того, чтобы процессор мог эффективнее загружать 32-битные 
значения из памяти через шину с памятью, кэш-память, итд.

\input{patterns/08_switch/2_lot/olly_RU}

\myparagraph{\NonOptimizing GCC}
\label{switch_lot_GCC}

Посмотрим, что сгенерирует GCC 4.4.1:

\lstinputlisting[caption=GCC 4.4.1,style=customasmx86]{patterns/08_switch/2_lot/lot_gcc.asm}

\myindex{x86!\Registers!JMP}
Практически то же самое, за исключением мелкого нюанса: аргумент из \TT{arg\_0} умножается на 4 
при помощи сдвига влево на 2 бита (это почти то же самое что и умножение на 4)~(\myref{SHR}).
Затем адрес метки внутри функции берется из массива \TT{off\_804855C} и адресуется при помощи 
вычисленного индекса.

